<template>
  <div id="app">
    <!-- region 按钮组 -->
    <div style="display: flex; flex-direction: row; padding: 10px; justify-content: flex-start; width: 100%;">
      <el-popover placement="bottom" trigger="hover">
        <div style="display: flex; flex-direction: column; text-align: left; width: 400px; height: 164px;">
          <template v-for="(n, i) in 4">
            <puzzle-marker style="padding: 10px; font-size: 15px;" :key="n" :type="i" :show-text="true"/>
          </template>
        </div>
        <el-button slot="reference" size="mini" round plain type="info" style="margin: 0 10px;">图例说明</el-button>
      </el-popover>

      <el-button
        v-if="puzzleItems.length > 0"
        size="mini" round plain type="primary"
        @click="selecting = !selecting; current = null; selectedItems.length = 0;"
      >
        {{ selecting ? '取消选择': '选择' }}
      </el-button>
      <template v-if="!selecting && showMode === 'query'">
        <el-button size="mini" round plain @click="showMode = 'item'; refresh();">本地关卡</el-button>
        <el-button size="mini" round plain @click="queryVisible = true">创意工坊查询</el-button>
      </template>
      <template v-if="!selecting && showMode === 'item'">
        <el-button size="mini" round plain @click="refresh">刷新</el-button>
        <el-button size="mini" round plain @click="newPuzzle">新建普通关卡</el-button>
        <el-button size="mini" round plain @click="queryVisible = true">创意工坊查询</el-button>
        <el-button size="mini" round plain @click="execCommand('screenshot')">打开截图文件夹</el-button>
        <el-button size="mini" round plain @click="execCommand('puzzle')">打开关卡文件夹</el-button>
        <el-button size="mini" round plain type="primary" @click="execCommand('portal2')">运行Portal 2</el-button>
      </template>
      <el-button size="mini" round plain v-if="selecting" type="warning"
       @click="selectedItems.length = 0; selectedItems.push(...puzzleItems)">
        全选
      </el-button>
      <el-button size="mini" round plain v-if="selecting" type="warning"
       @click="selectedItems.length = 0; selectedItems.pop();">
        全不选
      </el-button>

      <template v-if="selecting && selectedItems.length">
        <el-button size="mini" round plain @click="operateBatch('subscribe')">订阅</el-button>
        <el-button size="mini" round plain @click="operateBatch('unsubscribe')">取消订阅</el-button>
        <el-button size="mini" round plain @click="operateBatch('favorite')">收藏</el-button>
        <el-button size="mini" round plain @click="operateBatch('unfavorite')">取消收藏</el-button>
        <el-button size="mini" round plain @click="operateBatch('voteUp')">好评</el-button>
        <el-button size="mini" round plain @click="operateBatch('voteDown')">差评</el-button>
        <el-button size="mini" round plain @click="operateBatch('markAsPlayed')">标记为已玩过</el-button>
        <el-button size="mini" round plain @click="copyItemUrls(...selectedItems.map(item => item.fileId))">复制链接</el-button>
      </template>
    </div>
    <!-- endregion -->

    <!-- region 关卡列表 -->
    <div style="
      display: flex;
      flex-direction: row;
      flex-wrap: wrap;
      height: 100%;
      align-content: flex-start;
      overflow: auto;" v-if="puzzleItems.length > 0">
      <div v-for="(item, index) in puzzleItemsPage" :key="index" style="width: 200px; padding: 5px;" @click="clickItem(item)">
        <el-card shadow="hover" style="height: 180px; cursor: pointer;" :style="selectedItems.includes(item) && {borderColor: 'blue'}">
          <el-image
            style="width: 100%; height: 100px;"
            fit="contain"
            :src="getAbsoluteUrl(item.workshop.preview || item.local.preview)"
          />
          <span style="font-size: 13px;">
            {{ item.local.title || item.workshop.title }}
            <puzzle-marker :type="item.type"/>
          </span>
        </el-card>
      </div>
    </div>

    <el-pagination
      background
      hide-on-single-page
      layout="total, sizes, prev, pager, next, jumper"
      :total="puzzleItems.length"
      :current-page.sync="currentPage"
      :page-size.sync="pageSize"
      style="margin: 5px;"
    />

    <el-card v-if="puzzleItems !== initPuzzleItems && puzzleItems.length === 0" style="height: 100%; margin: 5px; position: relative;">
      <img src="@/assets/img/200.gif" style="
        position: absolute;
        left: 0;
        top: 0;
        width: 100%;
        height: 100%;
        object-fit: cover;
      "/>
      <div style="
        position: absolute;
        left: 0;
        top: 0;
        width: 100%;
        height: 100%;
        color: deepskyblue;
        display: flex;
        letter-spacing: 5px;
        flex-direction: column;
        justify-content: center;
      "><h1>没查到数据哦～</h1></div>
    </el-card>
    <!-- endregion -->

    <toast/>

    <!-- region 关卡信息弹窗 -->
    <el-drawer :visible.sync="visible" size="570px">
      <div v-if="current" style="padding: 10px; display: flex; flex-direction: column; height: 100%;">
        <el-image
          style="width: 100%; height: 188px;"
          fit="contain"
          :src="getAbsoluteUrl(current.workshop.preview || current.local.preview)"
          :preview-src-list="[getAbsoluteUrl(current.workshop.preview || current.local.preview)]"
        />
        <div style="flex: 1; overflow: auto; padding: 10px 0;">
          <el-descriptions direction="vertical" :column="3" border>
            <div slot="title">
              {{ current.local.title || current.workshop.title }}
              <el-tag size="mini">{{ current.coop ? '合作' : '单人' }}</el-tag>
              <template v-if="showMode === 'item'">
                <puzzle-marker :type="current.type"/>
              </template>
            </div>
            <el-descriptions-item label="操作" :span="3">
              <div style="display: flex; gap: 10px; flex-wrap: wrap;">
                <el-button size="mini" style="margin: 0;" round plain @click="operateBatch('subscribe')">订阅</el-button>
                <el-button size="mini" style="margin: 0;" round plain @click="operateBatch('unsubscribe')">取消订阅</el-button>
                <el-button size="mini" style="margin: 0;" round plain @click="operateBatch('favorite')">收藏</el-button>
                <el-button size="mini" style="margin: 0;" round plain @click="operateBatch('unfavorite')">取消收藏</el-button>
                <el-button size="mini" style="margin: 0;" round plain @click="operateBatch('voteUp')">好评</el-button>
                <el-button size="mini" style="margin: 0;" round plain @click="operateBatch('voteDown')">差评</el-button>
                <el-button size="mini" style="margin: 0;" round plain @click="operateBatch('markAsPlayed')">标记为已玩过</el-button>
                <el-button size="mini" style="margin: 0;" @click="copyItemUrls(current.fileId)" round plain>复制链接</el-button>
                <el-button size="mini" style="margin: 0;" @click="showClone" round plain>克隆关卡</el-button>
              </div>
            </el-descriptions-item>
            <el-descriptions-item label="文件ID" :span="3">
              {{ current.fileId || '暂未发布' }}
              <template v-if="current.fileId > 0">
                <el-button
                  size="mini" round plain type="primary"
                  @click="showInWorkshop(current.fileId)">
                  在创意工坊中查看
                </el-button>
                <el-button size="mini" @click="copyItemUrls(current.fileId)" round plain type="info">复制链接</el-button>
                <el-button size="mini" @click="showClone" round plain type="info">克隆关卡</el-button>
              </template>
              <template v-if="current.type !== 2">
                <el-button size="mini" round plain type="warning" @click="bindVisible = true">绑定物品</el-button>
                <el-button size="mini" round plain type="danger" v-if="current.fileId > 0" @click="unbind">解绑物品</el-button>
              </template>
            </el-descriptions-item>
            <template v-if="current.type !== 2">
              <el-descriptions-item label="本地标题" :span="3">{{ current.local.title }}</el-descriptions-item>
              <el-descriptions-item label="本地描述" :span="3">
                <pre style="margin: 0; white-space: pre-wrap; word-wrap: break-word;">{{ current.local.description }}</pre>
              </el-descriptions-item>
              <el-descriptions-item label="本地创建时间">{{ current.local.createTime }}</el-descriptions-item>
              <el-descriptions-item label="本地修改时间" :span="2">{{ current.local.updateTime }}</el-descriptions-item>
              <el-descriptions-item label="本地文件名" :span="2">{{ current.local.mapFileName }}</el-descriptions-item>
              <el-descriptions-item label="本地文件大小">{{ current.local.mapFileSize | fileSize }}</el-descriptions-item>
              <el-descriptions-item label="源文件名" :span="2">
                {{ current.puzzleFileName }}
                <el-button size="mini" round plain type="warning" @click="rename">重命名</el-button>
              </el-descriptions-item>
              <el-descriptions-item label="实验室大小">
                {{ current.chamberSize ? current.chamberSize.replaceAll(' ', ' × ') : '' }}
              </el-descriptions-item>
            </template>
            <template v-if="current.type === 1 || current.type === 2">
              <el-descriptions-item label="创意工坊标题" :span="3">{{ current.workshop.title }}</el-descriptions-item>
              <el-descriptions-item label="创意工坊描述" :span="3">
                <pre
                    style="margin: 0; white-space: pre-wrap; word-wrap: break-word;">{{ current.workshop.description }}</pre>
              </el-descriptions-item>
              <el-descriptions-item label="创意工坊创建时间">{{ current.workshop.createTime }}</el-descriptions-item>
              <el-descriptions-item label="创意工坊修改时间" :span="2">{{ current.workshop.updateTime }}</el-descriptions-item>
              <el-descriptions-item label="创意工坊文件名" :span="2">{{ current.workshop.mapFileName }}</el-descriptions-item>
              <el-descriptions-item label="创意工坊文件大小">{{ current.workshop.mapFileSize | fileSize }}</el-descriptions-item>
              <el-descriptions-item label="标签" :span="3" v-if="current.tags">
                <el-tag size="mini" type="info" v-for="tag in convertTags(current.tags)" :key="tag">{{ tag }}</el-tag>
              </el-descriptions-item>
              <el-descriptions-item label="可见性">
                <span v-if="current.visibility === 0">公开</span>
                <span v-if="current.visibility === 1">仅限好友</span>
                <span v-if="current.visibility === 2">私有</span>
                <span v-if="current.visibility === 3">非公开</span>
              </el-descriptions-item>
            </template>
          </el-descriptions>
        </div>
        <el-button v-if="showMode === 'item'" round plain type="primary" @click="showUpdate">更新物品</el-button>
      </div>
    </el-drawer>
    <!-- endregion -->

    <!-- region 绑定物品 -->
    <el-drawer :visible.sync="bindVisible" size="570px" direction="ltr">
      <div style="display: flex; flex-direction: column; height: 100%; padding: 10px;">
        <div style="display: flex; flex-direction: row; flex-wrap: wrap; overflow: auto; flex: 1; align-content: flex-start; justify-content: center;">
          <div v-for="(item, index) in puzzleItems.filter(t => t.type === 2)" :key="index"
               style="width: 200px; padding: 5px;"
               @click="bindCurrent = item;">
            <el-card shadow="hover" style="height: 180px; cursor: pointer;" :style="bindCurrent === item && {borderColor: 'blue'}">
              <el-image
                style="width: 100%; height: 100px;"
                fit="contain"
                :src="getAbsoluteUrl(item.workshop.preview || item.local.preview)"
              />
              <span style="font-size: 13px;" v-if="showMode === 'item'">
                {{ item.local.title || item.workshop.title }}
                <puzzle-marker :type="item.type"/>
              </span>
            </el-card>
          </div>
        </div>
        <div>
          <el-button round plain type="primary" @click="bind(); bindVisible = false;">确定</el-button>
          <el-button round plain type="warning" @click="bindVisible = false;">取消</el-button>
        </div>
      </div>
    </el-drawer>
    <!-- endregion -->

    <!-- region 更新物品 -->
    <el-drawer :visible.sync="updateVisible" size="570px" direction="ltr">
      <el-form v-if="formData" :model="formData" ref="formUpdate" label-width="150px" style="padding: 10px;" label-position="left">
        <template v-if="formData.type !== 2">
          <el-form-item label="本地标题" prop="local.title" required>
            <el-input v-model="formData.local.title"/>
          </el-form-item>
          <el-form-item label="本地描述" prop="local.description" required>
            <el-input type="textarea" v-model="formData.local.description" :rows="6" resize="none"/>
          </el-form-item>
        </template>
        <el-form-item v-if="formData.type === 2" label="双人合作谜题" prop="coop">
          <div style="text-align: left;"><el-switch v-model="formData.coop"/></div>
        </el-form-item>
        <el-form-item  v-if="formData.type === 0" label-width="0px">
          <div style="display: flex; justify-content: flex-start;">
            <el-checkbox v-model="publish">发布关卡</el-checkbox>
          </div>
        </el-form-item>
        <template v-if="formData.type !== 0 || publish">
          <el-form-item label="创意工坊标题" prop="workshop.title" required>
            <el-input v-model="formData.workshop.title"/>
          </el-form-item>
          <el-form-item label="创意工坊描述" prop="workshop.description" required>
            <el-input v-model="formData.workshop.description" type="textarea" :rows="6" resize="none"/>
          </el-form-item>
          <el-form-item label="可见范围" prop="visibility" required>
            <el-select v-model="formData.visibility" style="width: 100%;">
              <el-option label="公开" :value="0"/>
              <el-option label="仅限好友" :value="1"/>
              <el-option label="私有" :value="2"/>
              <el-option label="非公开" :value="3"/>
            </el-select>
          </el-form-item>
          <el-form-item label="预览图" prop="previewFilePath" :required="publish || updatePreview">
            <el-tooltip :content="formData.previewFilePath" :disabled="!formData.previewFilePath || (!publish && !updatePreview)" placement="right-start">
              <el-image
                style="width: 100%; height: 200px;"
                fit="contain"
                :src="getAbsoluteUrl((publish || updatePreview ? formData.local : formData.workshop).preview)"
                :preview-src-list="[getAbsoluteUrl((publish || updatePreview ? formData.local : formData.workshop).preview)]"
              />
            </el-tooltip>
            <el-checkbox v-if="!publish" v-model="updatePreview">更新预览图</el-checkbox>
            &nbsp;&nbsp;
            <el-button :disabled="!publish && !updatePreview" size="mini" plain round type="primary" @click="choosePreviewFile">选择文件</el-button>
          </el-form-item>
          <el-form-item label="关卡文件" prop="mapFilePath" :required="publish || updateMap">
            <el-tooltip :content="formData.mapFilePath" :disabled="!formData.mapFilePath || (!publish && !updateMap)" placement="right-start">
              <el-card style="width: 100%; height: 200px; margin-bottom: 5px;">
                <div style="display: flex; flex-direction: column; justify-content: space-between;">
                  <template v-if="(publish || updateMap ? formData.local : formData.workshop).mapFileName">
                    <h1>{{ (publish || updateMap ? formData.local : formData.workshop).mapFileName }}</h1>
                    <h3>{{ (publish || updateMap ? formData.local : formData.workshop).mapFileSize | fileSize }}</h3>
                  </template>
                </div>
              </el-card>
            </el-tooltip>
            <el-checkbox v-if="!publish" v-model="updateMap">更新关卡文件</el-checkbox>
            &nbsp;&nbsp;
            <el-button
              :disabled="!publish && !updateMap"
              size="mini" plain round type="primary"
              @click="chooseMapFile"
            >选择文件</el-button>
          </el-form-item>
          <el-form-item label="标签" prop="tags">
            <div style="text-align: left; display: flex; flex-wrap: wrap;">
              <el-tag size="mini" type="info" v-for="tag in convertTags(formData.tags)" style="margin: 5px;" :key="tag">{{ tag }}</el-tag>
              <el-tag size="mini" @click="tagsVisible = true" style="cursor: pointer; margin: 5px;">选择</el-tag>
            </div>
          </el-form-item>
        </template>
        <el-form-item label-width="0px">
          <el-button round plain type="primary" style="width: 100%;" @click="submit">提交</el-button>
        </el-form-item>
      </el-form>
    </el-drawer>
    <!--endregion -->

    <el-drawer :visible.sync="tagsVisible">
      <div style="text-align: left; padding: 10px; margin: 10px;" v-if="formData">
        <el-divider>官方标签</el-divider>
        <el-tag
          v-for="tag in officialTags"
          size="mini"
          :key="tag.name"
          :type="formData.tags.includes(tag.name) ? '' : 'info'"
          style="margin: 5px;"
          @click="toggleTag(tag.name)"
        >
          {{ tag.title }}（{{ tag.name }}）
        </el-tag>
        <el-divider>其他标签</el-divider>
        <el-tag
          v-for="tag in extraTags"
          size="mini"
          :key="tag.name"
          :type="formData.tags.includes(tag.name) ? '' : 'info'"
          style="margin: 5px;"
          @click="toggleTag(tag.name)"
        >
          {{ tag.title }}（{{ tag.name }}）
        </el-tag>
        <el-button round plain type="primary" style="width: 100%;" @click="tagsVisible = false;">确定</el-button>
      </div>
    </el-drawer>

    <el-drawer :visible.sync="cloneVisible" size="570px" direction="ltr">
      <el-form v-if="formData" :model="formData" ref="formClone" label-width="150px" style="padding: 10px;" label-position="left">
        <el-form-item label="文件ID" prop="fileId" required>
          <el-input v-model="formData.fileId" readonly @change="changeFileId"/>
        </el-form-item>
        <template v-if="formData.type !== 2">
          <el-form-item label="本地标题" prop="local.title" required>
            <el-input v-model="formData.local.title"/>
          </el-form-item>
          <el-form-item label="本地描述" prop="local.description" required>
            <el-input type="textarea" v-model="formData.local.description" :rows="6" resize="none"/>
          </el-form-item>
        </template>
        <el-form-item label="创意工坊标题" prop="workshop.title" required>
          <el-input v-model="formData.workshop.title"/>
        </el-form-item>
        <el-form-item label="创意工坊描述" prop="workshop.description" required>
          <el-input v-model="formData.workshop.description" type="textarea" :rows="6" resize="none"/>
        </el-form-item>
        <el-form-item label="可见范围" prop="visibility" required>
          <el-select v-model="formData.visibility" style="width: 100%;">
            <el-option label="公开" :value="0"/>
            <el-option label="仅限好友" :value="1"/>
            <el-option label="私有" :value="2"/>
            <el-option label="非公开" :value="3"/>
          </el-select>
        </el-form-item>
        <el-form-item label="预览图" prop="workshop.preview" required>
          <el-image
            style="width: 100%; height: 200px;"
            fit="contain"
            :src="getAbsoluteUrl(formData.workshop.preview)"
            :preview-src-list="[getAbsoluteUrl(formData.workshop.preview)]"
          />
        </el-form-item>
        <el-form-item label="关卡文件" prop="workshop.mapFileName" required>
          <el-card style="width: 100%; height: 200px; margin-bottom: 5px;">
            <div style="display: flex; flex-direction: column; justify-content: space-between;">
              <h1>{{ formData.workshop.mapFileName }}</h1>
              <h3>{{ formData.workshop.mapFileSize | fileSize }}</h3>
            </div>
          </el-card>
        </el-form-item>
        <el-form-item label="标签" prop="tags">
          <div style="text-align: left;">
            <el-tag size="mini" type="info" v-for="tag in convertTags(formData.tags)" style="margin: 5px;" :key="tag">{{ tag }}</el-tag>
            <el-tag size="mini" @click="tagsVisible = true" style="cursor: pointer; margin: 5px;">选择</el-tag>
          </div>
        </el-form-item>
        <el-form-item label-width="0px">
          <el-button round plain type="primary" style="width: 100%;" @click="cloneMap">提交</el-button>
        </el-form-item>
      </el-form>
    </el-drawer>

    <el-drawer :visible.sync="queryVisible" size="570px" direction="ltr">
      <el-form :model="queryInfo" ref="formQuery" label-width="170px" style="padding: 10px;" label-position="left">
        <el-form-item label="查询方式" prop="queryWay" required>
          <el-select v-model="queryInfo.queryWay" style="width: 100%;">
            <el-option label="按作者" value="author"/>
            <el-option label="按物品" value="item"/>
          </el-select>
        </el-form-item>
        <el-form-item label="作者链接（或好友代码）" prop="authorUrl" v-if="queryInfo.queryWay === 'author'">
          <el-input
            type="text"
            v-model="queryInfo.authorUrl"
            placeholder="留空查询当前账号"
            @change="queryInfo.authorUrl && (queryInfo.authorType = 'published')"
          />
        </el-form-item>
        <el-form-item label="查询来源" prop="authorType" v-if="queryInfo.queryWay === 'author'" required>
          <el-select v-model="queryInfo.authorType" style="width: 100%;">
            <el-option :disabled="!!queryInfo.authorUrl" label="已订阅" value="subscribed"/>
            <el-option label="已发布" value="published"/>
            <el-option label="已收藏" value="favorited"/>
            <el-option :disabled="!!queryInfo.authorUrl" label="已评价" value="votedOn"/>
            <el-option :disabled="!!queryInfo.authorUrl" label="已好评" value="votedUp"/>
            <el-option :disabled="!!queryInfo.authorUrl" label="已差评" value="votedDown"/>
            <el-option label="已玩过" value="usedOrPlayed"/>
          </el-select>
        </el-form-item>
        <el-form-item label="物品链接" prop="itemUrl" v-if="queryInfo.queryWay === 'item'" required>
          <el-input type="textarea" v-model="queryInfo.itemUrl" :rows="6" resize="none"/>
        </el-form-item>
        <el-form-item label-width="0px">
          <el-button round plain type="primary" style="width: 100%;" @click="query">查询</el-button>
        </el-form-item>
      </el-form>
    </el-drawer>
  </div>
</template>

<script lang="ts">
/* eslint-disable @typescript-eslint/prefer-readonly */
import {Component, Ref, Watch} from 'vue-property-decorator';
import Toast from '@/components/common/Toast.vue';
import {registerEvents} from '@/utils/common_utils';
import BaseComponent from '@/components/common/BaseComponent';
import {
  getAbsoluteUrl,
  getPuzzleItems,
  openMapFile, openPreviewFile,
  rename, bind, execCommand, submit, cloneMap, showInWorkshop,
  init, queryWorkshopItem, query, operate,
  PuzzleItem, QueryInfo
} from '@/api/request/api';
import {MessageBoxInputData} from 'element-ui/types/message-box';
import {ElForm} from 'element-ui/types/form';
import PuzzleMarker from '@/PuzzleMarker.vue';

@Component({
  methods: {getAbsoluteUrl, showInWorkshop},
  components: {PuzzleMarker, Toast}
})
export default class App extends BaseComponent {
  private readonly initPuzzleItems: Array<PuzzleItem> = [];

  private puzzleItems = this.initPuzzleItems;

  private current: PuzzleItem = null;

  private bindCurrent: PuzzleItem = null;
  private formData: PuzzleItem = null;

  private updateMap = false;
  private updatePreview = false;
  private publish = false;
  private visible = false;
  private bindVisible = false;
  private updateVisible = false;
  private cloneVisible = false;
  private queryVisible = false;
  private tagsVisible = false;
  private pageSize = 100;
  private currentPage = 1;
  private showMode = 'item';
  private queryInfo: QueryInfo = {
    queryWay: 'item',
    authorType: 'published',
    authorUrl: '',
    itemUrl: ''
  };

  private selectedItems: Array<PuzzleItem> = [];

  private selecting = false;

  private readonly officialTags = [
    {name: 'Faith Plate', title: '弹射板'},
    {name: 'Light Bridge', title: '强光桥'},
    {name: 'Laser Emitter', title: '激光发射器'},
    {name: 'Laser Catcher', title: '激光接收器'},
    {name: 'Laser Relay', title: '激光中继器'},
    {name: 'Turret', title: '炮塔'},
    {name: 'Bounce Gel', title: '弹跳凝胶'},
    {name: 'Speed Gel', title: '加速凝胶'},
    {name: 'Conversion Gel', title: '转换凝胶'},
    {name: 'Cleansing Gel', title: '净化凝胶'},
    {name: 'Tractor Beam', title: '牵引光束'},
    {name: 'Tractor Beam Polarity', title: '牵引光束极性'},
    {name: 'Laser Field', title: '激光力场'},
    {name: 'Fizzler', title: '失效力场'},
    {name: 'Rail Platform', title: '轨道平台'},
    {name: 'Piston Platform', title: '活塞平台'},
    {name: 'Angled Panel', title: '有角面板'},
    {name: 'Glass Panel', title: '玻璃面板'},
    {name: 'Stairs', title: '楼梯'},
    {name: 'Button', title: '重量按钮'},
    {name: 'Cube Button', title: '方形按钮'},
    {name: 'Sphere Button', title: '球形按钮'},
    {name: 'Pedestal Button', title: '基座按钮'},
    {name: 'Weighted Cube', title: '重量方块'},
    {name: 'Weighted Cube Dropper', title: '重量方块掉落器'},
    {name: 'Companion Cube', title: '同伴方块'},
    {name: 'Companion Cube Dropper', title: '同伴方块掉落器'},
    {name: 'Reflector Cube', title: '反射方块'},
    {name: 'Reflector Cube Dropper', title: '反射方块掉落器'},
    {name: 'Edgeless Safety Cube', title: '球形方块'},
    {name: 'Edgeless Safety Cube Dropper', title: '球形方块掉落器'},
    {name: 'Franken Cube', title: '怪物方块'},
    {name: 'Franken Cube Dropper', title: '怪物方块掉落器'},
    {name: 'Goo', title: '致命粘液'},
    {name: 'Glass', title: '玻璃'},
    {name: 'Grating', title: '光栅'}
  ];

  private readonly extraTags = [
    {name: 'Reflection Gel', title: '反射凝胶'},
    {name: 'Death Fizzler', title: '致命失效力场'},
    {name: 'Absolute Fizzler', title: '强力失效力场'},
    {name: 'Paint Fizzler', title: '凝胶失效力场'},
    {name: 'Closed Solid Field', title: '白色力场'},
    {name: 'Physics Replusion Field', title: '绿色力场'},
    {name: 'Compressed Smoke Field', title: '紫色力场'},
    {name: 'Force Deflection Field', title: '橙色力场'},
    {name: 'Matter Inquistion Field', title: '黄色力场'},
    {name: 'Crusher', title: '粉碎机'},
    {name: 'High Energy Pellet', title: '能量球'},
    {name: 'High Energy Pellet Emiiter', title: '能量球发射器'},
    {name: 'High Energy Pellet Catcher', title: '能量球接受器'},
    {name: 'Rexaura Cube Deflector', title: '方块偏转器'},
    {name: 'Pistronic Energy Orb', title: '活塞能量球'},
    {name: 'Lifeform Sensor', title: '生命体传感器'},
    {name: 'Radiative Flux Rectangle', title: '能量球/火箭传感器'},
    {name: 'Conductive Plate', title: '导电板'},
    {name: 'Futbol', title: '玻璃球'},
    {name: 'Sendificator Slim', title: '激光传送器（小型）'},
    {name: 'Sendificator', title: '激光传送器'},
    {name: 'Pneumatic Diversity Vent', title: '气动分集排气阀'},
    {name: 'Vactubes', title: '真空管'},
    {name: 'Unstationary Scaffold Piston', title: '非自动脚手架活塞'},
    {name: 'Turret Dropper', title: '炮塔掉落器'},
    {name: 'Auto-Portal', title: '自动传送门'},
    {name: 'Portal Gun Pedestal', title: '可旋转传送门枪'},
    {name: 'Neurotoxin', title: '神经毒素'},
    {name: 'Rocket Turret', title: '火箭炮塔'},
    {name: 'Conveyor Belt', title: '传送带'},
    {name: 'BumbleBall', title: '弹力球'}
  ];

  @Ref('formUpdate')
  private formUpdate: ElForm;

  @Ref('formClone')
  private formClone: ElForm;

  @Ref('formQuery')
  private formQuery: ElForm;

  private get puzzleItemsPage() {
    const start = (this.currentPage - 1) * this.pageSize;
    const end = this.currentPage * this.pageSize;
    return this.puzzleItems.slice(start, end);
  }

  public override created() {
    registerEvents();
  }

  public override async mounted() {
    this.$toast.showLoading();
    await document.fonts.ready;
    this.puzzleItems = await getPuzzleItems();
    console.log(this.puzzleItems);
    await this.$sleep(500);
    this.$toast.close();
  }

  public override destroyed() {
    location.reload();
  }

  private convertTags(tags: Array<string>) {
    return tags.map(t => {
      const tag = this.officialTags.find(p => p.name === t) ?? this.extraTags.find(p => p.name === t);
      if (tag) {
        return tag.title + ' (' + tag.name + ')';
      }
      return t;
    });
  }

  private async unbind() {
    try {
      await this.$confirm('确定要解绑物品吗', '系统提醒', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
        center: true,
        closeOnClickModal: false
      });
      await bind(this.current.puzzleFileName, 0);
      this.$message({type: 'success', message: '解绑成功'});
      this.current.fileId = 0;
      this.puzzleItems = await getPuzzleItems();
    } catch {
      // ignore
    }
  }

  private async bind() {
    await bind(this.current.puzzleFileName, this.bindCurrent.fileId);
    this.current.fileId = this.bindCurrent.fileId;
    this.$message({type: 'success', message: '绑定成功'});
    this.puzzleItems = await getPuzzleItems();
  }

  private showUpdate() {
    this.publish = this.updatePreview = this.updateMap = false;
    this.formData = {...this.current};
    this.updateVisible = true;
    this.formUpdate?.resetFields();
  }

  private async choosePreviewFile() {
    const previewFile = await openPreviewFile();
    if (previewFile) {
      this.$set(this.formData.local, 'preview', previewFile.url);
      this.$set(this.formData, 'previewFilePath', previewFile.path);
    }
  }

  private async chooseMapFile() {
    const mapFile = await openMapFile();
    if (mapFile) {
      this.$set(this.formData.local, 'mapFileName', mapFile.fileName);
      this.$set(this.formData.local, 'mapFileSize', mapFile.fileSize);
      this.$set(this.formData, 'mapFilePath', mapFile.path);
    }
  }

  private toggleTag(tag: string) {
    if (this.formData.tags.includes(tag)) {
      const index = this.formData.tags.indexOf(tag);
      this.formData.tags.splice(index, 1);
    } else {
      this.formData.tags.push(tag);
    }
  }

  private async rename() {
    const result = await this.$prompt('请输入新名称', '重命名') as MessageBoxInputData;
    const newName = result.value.endsWith('.p2c') ? result.value : result.value + '.p2c';
    await rename(this.current.puzzleFileName, newName);
    this.$message({type: 'success', message: '重命名成功'});
    this.puzzleItems = await getPuzzleItems();
  }

  private async execCommand(command: string) {
    await execCommand(command);
  }

  private async refresh() {
    this.$toast.showLoading();
    await init();
    this.puzzleItems = await getPuzzleItems();
    this.$toast.close();
  }

  private async submit() {
    try {
      await this.formUpdate.validate();
    } catch {
      return;
    }
    try {
      const commitData = {...this.formData};
      if (!this.publish && !this.updatePreview) {
        commitData.previewFilePath = null;
      }
      if (!this.publish && !this.updateMap) {
        commitData.mapFilePath = null;
      }
      this.$toast.showLoading();
      await submit(commitData);
      this.puzzleItems = await getPuzzleItems();
      this.updateVisible = false;
      this.$message.success('提交关卡完成');
    } finally {
      this.$toast.close();
    }
  }

  private newPuzzle() {
    this.publish = true;
    this.updatePreview = this.updateMap = false;
    this.formData = {
      fileId: 0,
      type: 2,
      previewFilePath: '',
      mapFilePath: '',
      workshop: {},
      local: {
        preview: '',
        mapFileSize: 0,
        mapFileName: ''
      },
      tags: []
    } as PuzzleItem;
    this.updateVisible = true;
    this.formUpdate?.resetFields();
  }

  private showClone() {
    this.formData = JSON.parse(JSON.stringify(this.current)) as PuzzleItem;
    this.cloneVisible = true;
    this.formClone?.resetFields();
  }

  private async query() {
    try {
      await this.formQuery.validate();
    } catch {
      return;
    }
    try {
      this.$toast.showLoading();
      this.puzzleItems = await query(this.queryInfo);
      this.queryVisible = false;
      this.showMode = 'query';
    } finally {
      this.$toast.close();
    }
  }

  private async cloneMap() {
    try {
      await this.formClone.validate();
    } catch {
      return;
    }
    try {
      const commitData = {...this.formData};
      this.$toast.showLoading();
      await cloneMap(commitData);
      this.puzzleItems = await getPuzzleItems();
      this.$message.success('克隆关卡完成');
      this.cloneVisible = false;
    } finally {
      this.$toast.close();
    }
  }

  private clickItem(item: PuzzleItem) {
    if (this.selecting) {
      if (item.fileId === 0) {
        return;
      }
      if (this.selectedItems.includes(item)) {
        const index = this.selectedItems.indexOf(item);
        this.selectedItems.splice(index, 1);
      } else {
        this.selectedItems.push(item);
      }
    } else {
      this.current = item;
      this.selectedItems.length = 0;
      this.selectedItems.push(this.current);
      this.visible = true;
    }
  }

  private async changeFileId() {
    this.formData = await queryWorkshopItem(this.formData.fileId);
  }

  private async operateBatch(type: string) {
    this.$toast.showProgress(0);
    let index = 0;
    const ids = this.selectedItems.filter(item => item.type === 1 || item.type === 2).map(item => item.fileId);
    try {
      for (const id of ids) {
        await operate(id, type);
        this.$toast.showProgress(100 * ++index / ids.length);
      }
      await this.$sleep(500);
      this.$message({type: 'success', message: '操作成功'});
    } finally {
      this.$toast.close();
    }
  }

  private async copyItemUrls(...fileIds: Array<number>) {
    await this.$copyText(fileIds.map(id => 'https://steamcommunity.com/sharedfiles/filedetails/?id=' + id).join('\r\n'));
    this.$toast('复制成功');
  }

  @Watch('puzzleItems', {deep: false})
  private watchPuzzleItems() {
    this.visible = false;
  }
}
</script>
